package exporter

import (
	"net/http"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/collectors"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

// Collector is the interface implemented by anything that can be used by
// Prometheus to collect metrics. A Collector has to be registered for
// collection. See Registerer.Register.
//
// The stock metrics provided by this package (Gauge, Counter, Summary,
// Histogram, Untyped) are also Collectors (which only ever collect one metric,
// namely itself). An implementer of Collector may, however, collect multiple
// metrics in a coordinated fashion and/or create metrics on the fly. Examples
// for collectors already implemented in this library are the metric vectors
// (i.e. collection of multiple instances of the same Metric but with different
// label values) like GaugeVec or SummaryVec, and the ExpvarCollector.
// type Collector interface {
// 	// Describe sends the super-set of all possible descriptors of metrics
// 	// collected by this Collector to the provided channel and returns once
// 	// the last descriptor has been sent. The sent descriptors fulfill the
// 	// consistency and uniqueness requirements described in the Desc
// 	// documentation.
// 	//
// 	// It is valid if one and the same Collector sends duplicate
// 	// descriptors. Those duplicates are simply ignored. However, two
// 	// different Collectors must not send duplicate descriptors.
// 	//
// 	// Sending no descriptor at all marks the Collector as “unchecked”,
// 	// i.e. no checks will be performed at registration time, and the
// 	// Collector may yield any Metric it sees fit in its Collect method.
// 	//
// 	// This method idempotently sends the same descriptors throughout the
// 	// lifetime of the Collector. It may be called concurrently and
// 	// therefore must be implemented in a concurrency safe way.
// 	//
// 	// If a Collector encounters an error while executing this method, it
// 	// must send an invalid descriptor (created with NewInvalidDesc) to
// 	// signal the error to the registry.
// 	Describe(chan<- *Desc)
// 	// Collect is called by the Prometheus registry when collecting
// 	// metrics. The implementation sends each collected metric via the
// 	// provided channel and returns once the last metric has been sent. The
// 	// descriptor of each sent metric is one of those returned by Describe
// 	// (unless the Collector is unchecked, see above). Returned metrics that
// 	// share the same descriptor must differ in their variable label
// 	// values.
// 	//
// 	// This method may be called concurrently and must therefore be
// 	// implemented in a concurrency safe way. Blocking occurs at the expense
// 	// of total performance of rendering all registered metrics. Ideally,
// 	// Collector implementations support concurrent readers.
// 	Collect(chan<- Metric)
// }

var (
	C *AppCollector
)

func NewAppCollector() *AppCollector {
	return &AppCollector{
		OperateLogCount: prometheus.NewDesc("operate_log_count", "从kafka消费的操作日志统计", nil, nil),
	}
}

// 应用程序自定义监控指标采集器
type AppCollector struct {
	OperateLogCount *prometheus.Desc
	// 这个值是一个Counter
	operateLogCount float64
}

// 控制这个值进行计数
func (c *AppCollector) OperateLogCountInc() {
	c.operateLogCount++
}

// 发送我们的指标元数据
func (c *AppCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- c.OperateLogCount
}

// 数据的采集
func (c *AppCollector) Collect(ch chan<- prometheus.Metric) {
	ch <- prometheus.MustNewConstMetric(
		c.OperateLogCount,
		prometheus.CounterValue, c.operateLogCount)
}

func BuildMetric() {
	// 通过一个采集器 进度多个指标的采集
	C = NewAppCollector()

	customRegistry := prometheus.NewRegistry()
	customRegistry.Register(collectors.NewGoCollector())
	customRegistry.Register(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))

	// 已经注册了
	err := customRegistry.Register(C)
	if err != nil {
		panic(err)
	}

	http.Handle("/metrics", promhttp.HandlerFor(customRegistry, promhttp.HandlerOpts{
		Registry: customRegistry,
	}))
	go http.ListenAndServe(":8050", nil)
}
